class Snake {
  // 蛇头
  head: HTMLElement;
  // 蛇体
  bodies: HTMLCollection;
  // 蛇容器
  container: HTMLElement;
  MIN: number = 0;
  MAX: number = 290;

  constructor() {
    this.container = document.querySelector(".box-snake") as HTMLElement;
    this.head = document.querySelector(".box-snake > div") as HTMLElement;
    this.bodies = this.container.getElementsByTagName("div");
  }

  // 获取蛇坐标
  get X() {
    return this.head.offsetLeft;
  }
  get Y() {
    return this.head.offsetTop;
  }

  // 设置蛇头的坐标
  set X(value) {
    // 减少更改次数
    if (this.X === value) return;
    const bd = this.bodies[1] as HTMLElement;
    if (bd && bd.offsetLeft === value) value = value > this.X ? this.X - 10 : this.X + 10;
    // 判断合法范围 MIN MAX
    this.checkBumpWall(value);
    // 判断蛇是否撞到自己了
    this.checkBumpOneself();
    this.moveBody();
    this.head.style.left = `${value}px`;
  }
  set Y(value) {
    if (this.Y === value) return;
    const bd = this.bodies[1] as HTMLElement;
    if (bd && bd.offsetTop === value) value = value > this.Y ? this.Y - 10 : this.Y + 10;
    // 判断合法范围 MIN MAX
    this.checkBumpWall(value);
    this.checkBumpOneself();
    this.moveBody();
    this.head.style.top = `${value}px`;
  }

  // 蛇增加身体的方法
  addBody() {
    // 向蛇容器中添加一个div
    // beforeend 结束标签之前的位置 最后
    console.log("增加下");
    this.container.insertAdjacentHTML("beforeend", "<div></div>");
  }

  // 蛇移动身体的方法
  moveBody() {
    // 从后往前更改: 因为需要获取前一个元素的X,Y坐标
    for (let i = this.bodies.length - 1; i > 0; i--) {
      // 获取前面一个元素位置
      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;
      // 赋值当前元素位置
      (this.bodies[i] as HTMLElement).style.left = `${X}px`;
      (this.bodies[i] as HTMLElement).style.top = `${Y}px`;
    }
  }

  // 判断是否撞墙了
  checkBumpWall(value: number) {
    if (value < this.MIN || value > this.MAX) {
      throw new Error("蛇撞墙啦 游戏结束");
    }
  }

  // 判断蛇是否撞到自己了
  checkBumpOneself() {
    for (let i = 1; i < this.bodies.length; i++) {
      const bd = this.bodies[i] as HTMLElement;
      if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {
        throw new Error("你个笨蛋 撞到自己啦~");
      }
    }
  }
}

export default Snake;